In this tutorial, we first briefly introduce the Bayesian paradigm for statistical inference and the concept of hierarchical Bayesian graphical model. We simulate some toy problems with R and illustrate how we can easily represent them and infer their parameters of interest by means of the Stan programming language and its interface Rstan for R. The second part of the tutorial is devoted to use the Bayesian hierarchical methodology to derive a set of Period-Luminosity-Metallicity relations from Gaia parallaxes and photometry in several bands.

1 Bayesian Graphical Models

1.1 The Bayesian paradigm

Bayesian inference is based on the Bayes rule:

\[ p\left(\Theta\mid\mathcal{D}\right)=\frac{p\left(\mathcal{D}\mid\Theta\right)\times p\left(\Theta\right)}{p\left(\mathcal{D}\right)}\,, \] where \(\mathcal{D}\) are the observations (data), \(\Theta\) are the parameters of a model proposed to explain the data and \(p\)’s represent (discrete or continuous) probability distributions. Given that the probability of the data is constant, we can drop it and rewrite the former expression as

\[ p\left(\Theta\mid\mathcal{D}\right)\propto p\left(\mathcal{D}\mid\Theta\right)\times p\left(\Theta\right)\,, \] where the right side represents the model, specified by the joint probability distribution \(p\left(\mathcal{D},\Theta\right)\) of the data and the parameters, which factorizes in:

  • The conditional distribution \(p\left(\mathcal{D}\mid\Theta\right)\) of the data given the parameters, the so called likelihood , which is a function of the parameters.
  • The prior distribution \(p\left(\Theta\right)\) of the parameters, which represents our knowledge about the parameters before observing the data.

The left side \(p\left(\Theta\mid\mathcal{D}\right)\) represents what we infer from the model, which is the joint posterior distribution of the parameters given the data. Computing this distribution requires computing the normalizing constant \(p\left(\mathcal{D}\right)\), which, in many cases, is an analytically untreatable task. Furthermore, if we only are interested in a subset \(\Phi\) of \(\left( \Theta \right)=\left( \Phi ,\Lambda \right)\), then we are faced to integrate (marginalize) the joint posterior distribution over the set \(\Lambda\) of nuisance parameters, which can be challenging again. Fortunately, these two obstacles may be circumvented by sampling from the posterior distribution by means of Markov Chain Monte Carlo (MCMC) simulation technics.

1.2 A toy problem, DAG models and Stan

Let us now consider a very simple problem: To infer the mean \(\mu\) of a \(\mathsf{N}\left(\mu=3,\sigma=0.5\right)\) assuming that we known its standard deviation \(\sigma=0.5\). We first simulate some data:

N = 3000
x.mu = 3
x.sigma = 0.5
x.samples = rnorm(N, x.mu , x.sigma)
hist(x.samples,breaks=100,xlab="x",main="",freq=FALSE)

A model for this problem is: \[ p\left(\mathcal{D},\mu\right)=\prod_{i=1}^{N}p\left(\hat{x}_{i}\mid\mu\right)\times p\left(\mu\right) \] where \(\hat{x}_{i}\mid\mu\sim\mathsf{N}\left(\mu,4\right)\), \(\mu\sim\mathsf{N}\left(0,\sigma_{0}\right)\), with \(\sim\) meaning distributed as, and \(\sigma_0\) is a hyperparameter that represents our uncertainty about our prior knowledge about the true value of the mean, which we assume to be 0.

For a better understanding of the dependency structure between variables it is customary to represent the model by using the Bayesian network formalism, which consists of drawing a DAG (directed acyclic graph) whose topology represents the factorization of the joint probability distribution \(p\left(\mathcal{D},\Theta\right)\). So, we assign to each node of the DAG a factor distribution of \(p\left(\mathcal{D},\Theta\right)\). If the factor distribution is a conditional distribution, then the node parents are the parameters of the distribution and if the factor distribution is an unconditional (marginal) distribution, the node has no parents.

Now, to declare and draw the DAG corresponding to our toy model we use the dot language and call the grViz function of the DiagrammeR package.

library(DiagrammeR)
grViz("
  digraph BGMexample1 {
    margin=0;
    ratio=0.6; 
    compound=true; 
    node[style=filled,shape=circle,color=black, fillcolor=cadetblue3,fixedsize=false];
    rankdir =TB;
    
    subgraph cluster0 {
      
      label='N';
      # Observations
      # https://github.com/rich-iannone/DiagrammeR/issues/71
      x_rec[label='x̂@_{i}',shape=doublecircle]; 
    }
    # Parameters
    mu[label='μ'];
    sigma[label='σ',shape=square];
   # Links to observed nodes
    mu -> x_rec;
    sigma -> x_rec;
  }
 ", width = 400, height = 400  )

To do the Bayesian analysis we need a probabilistic modelling language in which we can declare our model and a MCMC sampler to perform the inference. In this tutorial we use the Stan language and its default sampler NUTS (No-U-Turn sampler). To run Stan from R we load the interface rstan:

library(rstan)
library(ggplot2)
rstan_options(auto_write = TRUE)
options(mc.cores = parallel::detectCores())

We define now the Stan model for our toy problem:

stanBGM1 <-'
  data {                     
    int<lower=0> N;            
    vector[N] obsx;           
    real<lower=0> sigma;
    real<lower=0> sigma0;
  }
  parameters {                
    real mu;
  }
  model {                    
    //prior
    mu ~ normal(0, sigma0);             
 
    //likelihood
    for (n in 1:N) {
      obsx[n] ~ normal(mu, sigma);
    }
  }
'

Now, we load our data into a list, call the sampler and store the results of the fit:

# Load data 
dat = list(N = N, obsx=x.samples, sigma=x.sigma, sigma0=100)

set.seed(12354)


fit1 <- stan(model_code = stanBGM1, data = dat, chains = 3,  iter = 6000  , warmup = 3000, verbose = FALSE)

Finally, we print the results and plot the Markov chains and a histogram corresponding to the posterior samples of \(\mu\):

# summary
print(fit1, digits_summary=4)
Inference for Stan model: b8858ef90e762465aa83bc5f8a8e20d3.
3 chains, each with iter=6000; warmup=3000; thin=1; 
post-warmup draws per chain=3000, total post-warmup draws=9000.

          mean se_mean     sd      2.5%       25%       50%       75%     97.5% n_eff   Rhat
mu      3.0346  0.0004 0.0225    2.9899    3.0196    3.0349    3.0500    3.0776  3002 1.0018
lp__ -228.4948  0.0118 0.7181 -230.4073 -228.6794 -228.2175 -228.0369 -227.9874  3712 1.0005

Samples were drawn using NUTS(diag_e) at Mon Nov 13 20:00:04 2017.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
stan_trace(fit1,pars=c("mu"),unconstrain = FALSE)

stan_hist(fit1,pars=c("mu"),unconstrain = FALSE)

1.3 Hierarchical Modelling

A hierarchical Bayesian model (HBM) divides the variability of a statistical problem into several levels.

Consider the following problem: To infer the mean \(\mu\) and the standard deviation \(\sigma\) of a Gaussian population from \(N\) samples of observed values with their corresponding uncertainties. First, let us to simulate some data:

N <- 500
x.mu <- 3
x.sigma <- 0.5
x.samples <- rnorm(N, x.mu , x.sigma)
x.obs.errors <- rnorm(N,0,1) 
x.obs.errors <- abs(x.obs.errors)
x.obs.samples <- rnorm(N, x.samples, x.obs.errors)  
hist(x.samples,breaks=100,xlab="x",main="",freq=FALSE,xlim=c(0,6),ylim=c(0,1))

hist(x.obs.samples,breaks=100,xlab="x",main="",freq=FALSE,xlim=c(0,6),ylim=c(0,1))

A suitable model for this problem is:

\[ p\left(\mathcal{D},\mu\right)=p\left(\mu\right)\cdot p\left(\sigma\right)\prod_{i=1}^{N}p\left(\hat{x}_{i}\mid x_{i}\right)\cdot p\left(x_{i}\mid\mu,\sigma\right) \]

where \(\hat{x}_{i}\mid x_{i}\sim\mathsf{N}\left(x_{i},\sigma_{x_{i}}\right)\), \(x_{i}\mid\mu,\sigma\sim\mathsf{N}\left(\mu,\sigma\right)\), \(\mu\sim\mathsf{N}\left(\mu_{0},\sigma_{0}\right)\) and \(\sigma\sim\mathsf{U}\left(0,k\right)\). That is, we distinguish between the intrinsic variability of the statistical problem (the variability at a population level) and the variability of each observation.

Now, we declare and draw the DAG corresponding to our HBM:

grViz("
  digraph BGMexample2 {
    margin=0;
    ratio=0.6; 
    compound=true; 
    node[style=filled,shape=circle,color=black, fillcolor=gray,fixedsize=false];
    rankdir =TB;
    
    subgraph cluster0 {
      
      label='N';
      
      # Parameters
      x[label='x@_{i}'];
      # Observations
      # https://github.com/rich-iannone/DiagrammeR/issues/71
      x_rec[label='x&#770;@_{i}',shape=doublecircle,fillcolor=deepskyblue1]; 
    }
    # Hyperparameters
    mu[label='&mu;',fillcolor=darkseagreen3];
    sigma[label='&sigma;',fillcolor=darkseagreen3];
   # Links 
    mu -> x;
    sigma -> x;
    x -> x_rec;
  }
 ", width = 600, height = 600  )

We define now the Stan model for our second problem:

stanBGM2 <-'
  data {                     
    int<lower=0> N;            
    vector[N] obsx;           
    vector<lower=0>[N] sigmaobsx;       
  }
  parameters {                
    real mu;
    real<lower=0> sigma;
    vector[N] x;   
  }
  model {                    
    # hyperpriors
    mu ~ normal(0, 10); 
    sigma ~ uniform(0, 10);    
    # priors
    for (n in 1:N) {
      x[n] ~ normal(mu, sigma);
    
    # Likelihood  
      obsx[n] ~ normal(x[n], sigmaobsx[n]);
    }
  }
'

Finally, we call the sampler and print summary statistics of the posterior samples for the the parameters \(\mu\) and \(\sigma\).

# Create the data list object
dat = list(N = N, obsx=x.obs.samples, sigmaobsx=x.obs.errors)


fit1 <- stan(model_code = stanBGM2, chains = 1, data = dat, iter = 1, verbose = FALSE)

set.seed(12354)

fit2 = stan(fit=fit1 , data = dat,  iter = 5000  , warmup = 3000, chains = 3)
# summary
print(fit2, pars=c("mu","sigma"), digits_summary=4)
Inference for Stan model: 59c7a279bc3a48dfa2b40aec2351c5fc.
3 chains, each with iter=5000; warmup=3000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=6000.

        mean se_mean     sd   2.5%    25%    50%    75%  97.5% n_eff   Rhat
mu    3.0301   5e-04 0.0355 2.9606 3.0058 3.0307 3.0540 3.0994  4170 1.0004
sigma 0.5194   8e-04 0.0320 0.4595 0.4978 0.5182 0.5404 0.5858  1467 1.0027

Samples were drawn using NUTS(diag_e) at Mon Nov 13 19:53:02 2017.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).

In the former example we have modelled the mean \(x_i\) of each individual observation \(\hat x_i\) and the mean \(\mu\) at a population level. As a consequence, we obtain shrunken (regularized) posterior estimates for each \(x_i\). Let us compare the results with a non-hierarchical pooled estimation:

stanBGM2pooled <-'
  data {                     
    int<lower=0> N;            
    vector[N] obsx;           
    vector<lower=0>[N] sigmaobsx;       
  }
  parameters {                
    real mu;
  }
  model {                    
    # priors
    mu ~ normal(0, 10); 
    for (n in 1:N) {
    # Likelihood  
      obsx[n] ~ normal(mu, sigmaobsx[n]);
    }
  }
'
# Create the data list object
dat = list(N = N, obsx=x.obs.samples, sigmaobsx=x.obs.errors)


fit21 <- stan(model_code = stanBGM2pooled, chains = 1, data = dat, iter = 1, verbose = FALSE)

set.seed(12354)

fit22 = stan(fit=fit21 , data = dat,  iter = 5000  , warmup = 3000, chains = 3)
# summary
print(fit22, digits_summary=4)
Inference for Stan model: 862a9dfe0d272562936ee493dbcbae43.
3 chains, each with iter=5000; warmup=3000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=6000.

           mean se_mean     sd       2.5%        25%        50%        75%      97.5% n_eff   Rhat
mu       2.8231  0.0001 0.0054     2.8125     2.8195     2.8231     2.8267     2.8335  1993 1.0001
lp__ -5602.8974  0.0145 0.7209 -5604.9294 -5603.0816 -5602.6151 -5602.4323 -5602.3840  2464 1.0002

Samples were drawn using NUTS(diag_e) at Mon Nov 13 19:53:49 2017.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).

We see that the hierarchical model improves the estimation of the true mean \(\mu=\) 3. In fact, the mean value of \(\mu\) inferred by the the HBM is 3.0301156 while the mean value inferred by the pooled estimator is 2.8230958.

1.4 Hierarchical Modelling for Regression

In this section we construct a HBM that infers the parameters of an intrinsic linear dependency relationship of the variable y on the variable x taking into account the measurement errors of both variables.

# 
N = 200
x.mu = -0.27790
x.sigma = 0.076

x.samples = rnorm(N, x.mu , x.sigma)
x.obs.errors <- rnorm(N,0,0.1) 
x.obs.errors <- abs(x.obs.errors)
x.obs.samples <- rnorm(N, x.samples, x.obs.errors)  

# 
# 
y.slope = -2.73
y.intercept = -1.24
y.sigma = 0.05
y.samples = rnorm(N, y.slope*x.samples + y.intercept , y.sigma)
y.obs.errors <- rnorm(N,0,0.1)
y.obs.errors <- abs(y.obs.errors)
y.obs.samples <- rnorm(N, y.samples, y.obs.errors) 


plot(x.samples, y.samples, asp = 1 )
plot(x.obs.samples, y.obs.samples, asp = 1 )

hist(y.samples,breaks=100)
hist(10^(x.samples),breaks=100)
cor(x.samples,y.samples)
cor(x.obs.samples,y.obs.samples)
# Create the stan model object
stanmodelcode <-'
data {                      
  int<lower=0> N;           
  vector[N] obsx;              
  vector[N] obsy;             
  vector<lower=0>[N] sigmaobsx;       
  vector<lower=0>[N] sigmaobsy;        
}
parameters {                 
  real mu;
  real alpha;               
  real beta1;
  real<lower=0> sigma;
  real<lower=0> sigmax;
  vector[N] x;               
  vector[N] y;
}
model {                    
  //priors
  alpha ~ normal(0, 10);             
  beta1 ~ normal(0, 10);
  sigma ~ uniform(0, 10);   
  sigmax ~ uniform(0, 10);
 
//likelihood
  for (n in 1:N) {
    x[n] ~ normal(mu, sigmax);
    y[n] ~ normal(alpha + beta1 * x[n], sigma);
    
    // Likelihood components

    obsx[n] ~ normal(x[n], sigmaobsx[n]);
    obsy[n] ~ normal(y[n], sigmaobsy[n]);

  }
}
'
# Create the data list object
dat = list(N = N, obsy=y.obs.samples, obsx=x.obs.samples,sigmaobsy=y.obs.errors,sigmaobsx=x.obs.errors)


fit1 <- stan(model_code = stanmodelcode, chains = 1, data = dat, iter = 1, verbose = FALSE)

set.seed(12354)

fit2 = stan(fit=fit1 , data = dat,  iter = 5000  , warmup = 3000, chains = 3)

# summary

print(fit2, digits_summary=4)

2 Bayesian models to Infer PL(Z) relations using Gaia parallaxes

In this section we construct a HBM to infer a Period-Lumninosity-Metallicity relation for RRL ab stars using Gaia parallaxes and photometry in the K-Band.

We first import the local file RRLyrae200Dambis.dat into a data frame and compute some derived parameters:


full <- read.table("RRLyrae200Dambis.dat",header=TRUE,na.strings = "NA",
                   colClasses =c(rep("character",3),rep("numeric",6),"character",
                                 rep("numeric",2),rep("character",1),rep("numeric",11)) )


n <- nrow(full)
full$K0    <- with(full, X.Kmag. - 0.114*AV ) 
full$em    <- with(full, e_.Kmag.) # Does not include uncertainty in dereddening
full$elogP <- with(full, LogP/(LogP*100) )   
full$emet  <- with(full, 0.2*Met_Harris/(Met_Harris) )     
#attach(full)
str(full)

Colums of data frame full include, for the n stars in the sample:

\(\left(\hat{m}_{i},\log\hat{P}_{i},\hat{\varpi}_{i},\hat{Z}_{i},\hat{A}_{m_{i}}\right)\)

Now, we are going to construct the HBM. Let us to present first the resulting DAG associated to the model. In the following paragraphs we detail its construction procedure.

We start modelling the stochastic linear relationship

\[ M_{i}=b+c\log P_{i}+kZ_{i} \]

where \(M_{i}\), \(\log P_{i}\) and \(Z_{i}\) are, respectively, the absolute magnitude, the decadic logarithm of the intrinsic period and the intrinsic metallicity of the i-th star in the sample. Note that we do not know the values of the intrinsic (true) astrophysical parameters \(\log P_{i}\) and \(Z_{i}\), but we do know their measured values \(\log\hat{P}_{i}\) and \(\hat{Z}_{i}\) and associated uncertainties. To account for the stochastic nature of the former relation, we assign it an intrinsic width \(w\). The main objective of the model is then to infer the parameters \(b\), \(c\), \(k\) and \(w\), where \(c=\tan\left(\phi_{1}\right)\) and \(k=\tan\left(\phi_{2}\right)\).

Now, we need to relate absolute magnitudes to apparent magnitudes. For that we use the deterministic relation \[ m_{i}=M_{i}-5\log\varpi_{i}+10+A_{m_{i}} \] , where \(m_{i}\) is the true reddened apparent magnitude and \(\varpi_{i}\) is the true parallax measured in mas. Note, again, that we do not know the values of true reddened apparent magnitudes and parallaxes but we do know their measured values \(\hat{m}_{i}\), \(\hat{\varpi}_{i}\) and uncertainties.

At this point we put into the DAG associated to our HBM, a rectangle that replicates with the \(n\) stars in the sample and include in it the nodes corresponding to extinctions \(A_{m_{i}}\) and true astrophysical parameters \(m_{i}\), \(M_{i}\), \(\log P_{i}\) and \(Z_{i}\) , and the arcs between these nodes, which are given by the two relations above. For example, we draw solid (stochastic) arcs from \(M_{i}\) to \(\log P_{i}\) and \(Z_{i}\) and dashed (deterministic) arcs from \(m_{i}\) to \(M_{i}\) and \(\varpi_{i}\). Outside the rectangle, we include the parameters \(b\), \(\phi_1\), \(\phi_2\) and \(w\) of the PLZ relation and trace the arcs from \(M_{i}\) to those nodes. We also set the distribution of the i-th absolute magnitude to a Gaussian of mean \(b+c\log P_{i}+kZ_{i}\) and standard deviation \(w\).

We continue the construction of the model and the DAG linking the measured astrophysical parameters to the true ones. So, we include \(\hat{m}_{i}\), \(\log\hat{P}_{i}\), \(\hat{\varpi}_{i}\) and \(\hat{Z}_{i}\) inside the rectangle of the DAG and trace the corresponding solid (stochastic) arcs to the true parameters. To each measured astrophysical parameter we assign a Gaussian distribution with its mean equal to the value of the true parameter and its standard deviation equal to the uncertainty provided by our data set. For example, for the measured apparent magnitude we declare \(\hat{m}_{i}\sim\mathsf{N}\left(m_{i},\sigma_{m_{i}}\right)\).

Next, we assign prior probability distributions to the true astrophysical parameters \(\log P_{i}\), \(Z_{i}\) and \(\varpi_{i}\) and trace the DAG arcs from these astrophysical parameters to the parameters of the distributions assigned to them. We set \(\log P_{i}\sim\mathsf{N}\left(\mu_{P}=0,\sigma_{P}=2\right)\), \(Z_{i}\sim\mathsf{N}\left(\mu_{Z}=0,\sigma_{Z}=5\right)\) and \(\varpi_{i}\sim\mathsf{logN}\left(\beta,\gamma\right)\). Note that the hyperparameters of the \(\log P_{i}\) and \(Z_{i}\) distributions are constant quantities while the hyperparameters \(\beta\) and \(\gamma\) of the \(\varpi_{i}\) distribution are random. For these latter ones we assign the hyperpriors \(\beta\sim\mathsf{N}\left(\mu_{\beta}=0,\sigma_{\beta}=2\right)\) and \(\gamma\sim\mathsf{Exp}\left(1\right)\).

To finish the BGM construction, we assign the following prior distributions to the parameters of the PLZ relation: \(b\sim\mathsf{N}\left(\mu_{\beta}=0,\sigma_{\beta}=10\right)\) to the intercept, \(\phi_{1},\phi_{2}\sim\mathsf{N}\left(\mu_{\phi}=0,\sigma_{\phi}=3.14/2\right)\) to the slope angles and \(w\sim\mathsf{Exp}\left(\lambda_{w}=1\right)\) to the spread.

We define now the Stan model for our problem:

stanPLZcode <-'
data {
  int<lower=1> N; // number of observations
  real pi[N];     // observed parallax
  real m[N];      // observed apparent magnitude 
  real logP[N];   // decadic logarithm of observed period 
  #real alpha[N];  // observed right ascension
  #real delta[N];  // observed declination
  real met[N];    // observed metallicity 
  real AV[N];
  
  real epi[N];    // measurement error of observed parallax
  real em[N];     // measurement error of observed (reddened) apparent magnitude 
  real elogP[N];  // measurement error of logarithm of observed period 
  real ealpha[N]; // measurement error of observed right ascension
  real edelta[N]; // measurement error of observed declination
  real emet[N];   // uncertainty of observed metallicity 
}
parameters {
  vector<lower=0>[N] pi0;   // true parallax
  vector[N] logP0;          // decadic logarithm of true period 
  vector[N] met0;           // true metallicity 
  vector[N] M;
  real angle;
  real b;
  real c;
  real beta;
  real gamma;
  real width;
  #real eAV;
}
model {
  #real ps;
  real a;
  real d;
  vector[N] emtot;
  #real emtot[N];
  width ~ exponential(1);
  beta ~ normal(0.0,2.0); 
  gamma ~ exponential(1);
  #eAV ~ normal(0,0.3); # RELATIVE error in extinction
  
  angle ~ normal(0,3.1416/2.0);
  b ~ normal(0,3.0);
  # c ~ normal(0,0.5);
  c ~ normal(0,3.1416/2.0);
  a = tan(angle);
  d = tan(c);
  for (i in 1:N) {
  pi0[i] ~ lognormal(beta,gamma);
  logP0[i] ~ normal(0.0,2);
  met0[i] ~ normal(0,5);
  M[i] ~ normal(a*logP0[i] + d*met0[i] + b, width); 
  #emtot[i] = sqrt(em[i]^2 + (0.114*AV[i]*fabs(eAV))^2);  
  #AV[i] ~ normal(0,0.2);
  # likelihood
  m[i] ~ normal(M[i] - (5.0*log10(pi0[i])) + 10.0 +AV[i] , em[i]);
  pi[i] ~ normal(pi0[i], epi[i]);
  logP[i] ~ normal(logP0[i],elogP[i]);
  met[i] ~ normal(met0[i],emet[i]);
  }
#  for (i in 1:N) {
#        ps = 
#          normal_lpdf(m[i]|(a*logP0[i]+d*met0[i]+b)+10.0-(5.0*log10(pi0[i]))  ,emtot[i]+width)+
#              normal_lpdf(pi[i]|pi0[i],epi[i])+
#              normal_lpdf(logP[i]|logP0[i],elogP[i])+
#              normal_lpdf(met[i]|met0[i],emet[i]);
#        target += ps;
#    }
}
'

We load the training set into a list, initialize Markov chains to random values, call the sampler, store the fit and extract posterior samples.

# Create data list object

linear_data <- list(N=nrow(full), pi=full$parallax, epi=full$parallax_error,
                    m=full$K0, em=full$em,
                    logP=full$LogP, elogP=full$elogP,
                    alpha=full$ra, delta=full$dec,
                    ealpha=full$ra_error, edelta=full$dec_error,
                    met=full$Met_Harris, emet=full$emet,
                    AV=full$AV 
                    )


str(linear_data)


initf2 <- function(chain_id = 1) {
  set.seed(chain_id)

# Create empty variables
  initpi = rep(NA,n)
  initlogp = rep(NA,n)
  initmet = rep(NA,n)
  initM = rep(NA,n)
# Initialize parameters
  m=rnorm(1,0,1.0) 
  angle = atan(m)
  b=rnorm(1,-1.0,0.3)
  c = rnorm(1,0,0.5)
  d = atan(c)

  width=rexp(1,1.0)
  beta=rnorm(1,0.0,2.0)
  gamma=rexp(1,1.0)
  eAV=rexp(1,1.0)
  
  for (i in 1:n) {
    initlogp[i] = rnorm(1,full$LogP[i],0.01)
    initmet[i] = rnorm(1,full$Met_Harris,0.5)
    initM[i] = rnorm(1, m*full$LogP[i] + c*full$Met_Harris[i] + b, width)
    initpi[i] =  10^((initM[i]- full$K0[i]+10.0)/5.0) # Initialize almost at random (m,b,d can take almost any value)
    
    
  }



 list(pi0=initpi,
         logP0=initlogp, M=initM,
          angle=angle,
          b=b, beta=beta, gamma=gamma, c=c, width=width,eAV=eAV)
 
 #list(angle=angle, b=b, beta=beta, gamma=gamma, c=c, width=width)
 
 

} 

# generate a list of lists to specify initial values
#n_chains <- 4
n_chains <- 1
init_ll <- lapply(1:n_chains, function(id) initf2(chain_id = id))

nsamples_chain =5000 #LSB
#nsamples_chain =1000
nsamples <- n_chains*nsamples_chain/2

fit <- stan(model_code = stanPLZcode, data = linear_data, iter = nsamples_chain, 
            chains = n_chains,init=init_ll,control= list(adapt_delta = 0.8), verbose = TRUE,init_r=2)

#fit <- stan(model_code = stanPLZcode, data = linear_data, iter = nsamples_chain, 
#            chains = n_chains,init="random",control= list(adapt_delta = 0.8), verbose = TRUE,init_r=2)

#draws <- extract(fit)

Finally, we plot the marginal posterior distributions from the MCMC samples.The diagonal shows the uni-dimensional marginal distributions for the intrinsic width of the relationship, the angle of the metallicity term in the linear relation, the intercept and the angle of the log(P) term.

pairs(fit, pars = c("width", "c", "b","angle"), labels=c("Intrinsic Width", "Metallicity Angle", "Intercept","log(P) Angle"), 
      log = FALSE, las = 1)

LS0tDQp0aXRsZTogIlIgbm90ZWJvb2sgdHV0b3JpYWwgYWJvdXQgaGllcmFyY2hpY2FsIEJheWVzaWFuIG1vZGVscyB0byBJbmZlciBQTChaKSByZWxhdGlvbnMgdXNpbmcgR2FpYSBwYXJhbGxheGVzIg0KYXV0aG9yOiANCi0gSMOpY3RvciBFLiBEZWxnYWRvDQotIEx1aXMgTS4gU2Fycm8NCmRhdGU6ICAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZC8lbS8lWScpYCINCmhlYWRlci1pbmNsdWRlczogDQogIC0gXHVzZXBhY2thZ2V7dGlren0NCiAgLSBcdXNlcGFja2FnZXtwZ2ZwbG90c30NCm91dHB1dDogDQogICAgaHRtbF9ub3RlYm9vazoNCiAgICAgIHRvYzogdHJ1ZQ0KICAgICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQotLS0NCg0KPHN0eWxlPg0KYm9keSB7DQp0ZXh0LWFsaWduOiBqdXN0aWZ5fQ0KPC9zdHlsZT4NCg0KDQoNCkluIHRoaXMgdHV0b3JpYWwsIHdlIGZpcnN0IGJyaWVmbHkgaW50cm9kdWNlIHRoZSBCYXllc2lhbiBwYXJhZGlnbSBmb3Igc3RhdGlzdGljYWwgaW5mZXJlbmNlIGFuZCB0aGUgY29uY2VwdCBvZiBoaWVyYXJjaGljYWwgQmF5ZXNpYW4gZ3JhcGhpY2FsIG1vZGVsLiBXZSBzaW11bGF0ZSBzb21lIHRveSBwcm9ibGVtcyB3aXRoIFIgYW5kIGlsbHVzdHJhdGUgaG93IHdlIGNhbiBlYXNpbHkgcmVwcmVzZW50IHRoZW0gYW5kIGluZmVyIHRoZWlyIHBhcmFtZXRlcnMgb2YgaW50ZXJlc3QgYnkgbWVhbnMgb2YgdGhlIFN0YW4gcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgYW5kIGl0cyBpbnRlcmZhY2UgUnN0YW4gZm9yIFIuIFRoZSBzZWNvbmQgcGFydCBvZiB0aGUgdHV0b3JpYWwgaXMgZGV2b3RlZCB0byB1c2UgdGhlIEJheWVzaWFuIGhpZXJhcmNoaWNhbCBtZXRob2RvbG9neSB0byBkZXJpdmUgYSBzZXQgb2YgUGVyaW9kLUx1bWlub3NpdHktTWV0YWxsaWNpdHkgcmVsYXRpb25zIGZyb20gR2FpYSBwYXJhbGxheGVzIGFuZCBwaG90b21ldHJ5IGluIHNldmVyYWwgYmFuZHMuICAgICANCg0KDQoNCiMgQmF5ZXNpYW4gR3JhcGhpY2FsIE1vZGVscw0KDQojIyBUaGUgQmF5ZXNpYW4gcGFyYWRpZ20gDQoNCkJheWVzaWFuIGluZmVyZW5jZSBpcyBiYXNlZCBvbiB0aGUgQmF5ZXMgcnVsZToNCg0KJCQNCnBcbGVmdChcVGhldGFcbWlkXG1hdGhjYWx7RH1ccmlnaHQpPVxmcmFje3BcbGVmdChcbWF0aGNhbHtEfVxtaWRcVGhldGFccmlnaHQpXHRpbWVzIHBcbGVmdChcVGhldGFccmlnaHQpfXtwXGxlZnQoXG1hdGhjYWx7RH1ccmlnaHQpfVwsLA0KJCQNCndoZXJlICRcbWF0aGNhbHtEfSQgYXJlIHRoZSBvYnNlcnZhdGlvbnMgKGRhdGEpLCAkXFRoZXRhJCBhcmUgdGhlIHBhcmFtZXRlcnMgb2YgYSBtb2RlbCBwcm9wb3NlZCB0byBleHBsYWluIHRoZSBkYXRhIGFuZCAkcCQncyByZXByZXNlbnQgKGRpc2NyZXRlIG9yIGNvbnRpbnVvdXMpIHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbnMuIEdpdmVuIHRoYXQgdGhlIHByb2JhYmlsaXR5IG9mIHRoZSBkYXRhIGlzIGNvbnN0YW50LCB3ZSBjYW4gZHJvcCBpdCBhbmQgcmV3cml0ZSB0aGUgZm9ybWVyIGV4cHJlc3Npb24gYXMNCg0KJCQNCnBcbGVmdChcVGhldGFcbWlkXG1hdGhjYWx7RH1ccmlnaHQpXHByb3B0byBwXGxlZnQoXG1hdGhjYWx7RH1cbWlkXFRoZXRhXHJpZ2h0KVx0aW1lcyBwXGxlZnQoXFRoZXRhXHJpZ2h0KVwsLA0KJCQNCndoZXJlIHRoZSByaWdodCBzaWRlIHJlcHJlc2VudHMgdGhlIG1vZGVsLCBzcGVjaWZpZWQgYnkgdGhlIGpvaW50IHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbiAkcFxsZWZ0KFxtYXRoY2Fse0R9LFxUaGV0YVxyaWdodCkkIG9mIHRoZSBkYXRhIGFuZCB0aGUgcGFyYW1ldGVycywgd2hpY2ggZmFjdG9yaXplcyBpbjoNCg0KKiBUaGUgY29uZGl0aW9uYWwgZGlzdHJpYnV0aW9uICRwXGxlZnQoXG1hdGhjYWx7RH1cbWlkXFRoZXRhXHJpZ2h0KSQgb2YgdGhlIGRhdGEgZ2l2ZW4gdGhlIHBhcmFtZXRlcnMsIHRoZSBzbyBjYWxsZWQgICpsaWtlbGlob29kICosIHdoaWNoIGlzIGEgZnVuY3Rpb24gb2YgdGhlIHBhcmFtZXRlcnMuDQoqIFRoZSAqcHJpb3IgZGlzdHJpYnV0aW9uKiAkcFxsZWZ0KFxUaGV0YVxyaWdodCkkIG9mIHRoZSBwYXJhbWV0ZXJzLCB3aGljaCByZXByZXNlbnRzIG91ciBrbm93bGVkZ2UgYWJvdXQgdGhlIHBhcmFtZXRlcnMgYmVmb3JlIG9ic2VydmluZyB0aGUgZGF0YS4NCg0KVGhlIGxlZnQgc2lkZSAkcFxsZWZ0KFxUaGV0YVxtaWRcbWF0aGNhbHtEfVxyaWdodCkkIHJlcHJlc2VudHMgd2hhdCB3ZSBpbmZlciBmcm9tIHRoZSBtb2RlbCwgd2hpY2ggaXMgdGhlICpqb2ludCBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uKiBvZiB0aGUgcGFyYW1ldGVycyBnaXZlbiB0aGUgZGF0YS4gQ29tcHV0aW5nIHRoaXMgZGlzdHJpYnV0aW9uIHJlcXVpcmVzIGNvbXB1dGluZyB0aGUgbm9ybWFsaXppbmcgY29uc3RhbnQgJHBcbGVmdChcbWF0aGNhbHtEfVxyaWdodCkkLCB3aGljaCwgaW4gbWFueSBjYXNlcywgaXMgYW4gYW5hbHl0aWNhbGx5IHVudHJlYXRhYmxlIHRhc2suIEZ1cnRoZXJtb3JlLCBpZiB3ZSBvbmx5IGFyZSBpbnRlcmVzdGVkIGluIGEgc3Vic2V0ICRcUGhpJCBvZiAkXGxlZnQoIFxUaGV0YSAgXHJpZ2h0KT1cbGVmdCggXFBoaSAsXExhbWJkYSAgXHJpZ2h0KSQsIHRoZW4gd2UgYXJlIGZhY2VkIHRvIGludGVncmF0ZSAobWFyZ2luYWxpemUpIHRoZSBqb2ludCBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIG92ZXIgdGhlIHNldCAkXExhbWJkYSQgb2YgKm51aXNhbmNlIHBhcmFtZXRlcnMqLCB3aGljaCBjYW4gYmUgY2hhbGxlbmdpbmcgYWdhaW4uIEZvcnR1bmF0ZWx5LCB0aGVzZSB0d28gb2JzdGFjbGVzIG1heSBiZSBjaXJjdW12ZW50ZWQgYnkgc2FtcGxpbmcgZnJvbSB0aGUgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbiBieSBtZWFucyBvZiBNYXJrb3YgQ2hhaW4gTW9udGUgQ2FybG8gKE1DTUMpIHNpbXVsYXRpb24gdGVjaG5pY3MuICAgDQoNCg0KDQojIyBBIHRveSBwcm9ibGVtLCBEQUcgbW9kZWxzIGFuZCBTdGFuIA0KDQpMZXQgdXMgbm93IGNvbnNpZGVyIGEgdmVyeSBzaW1wbGUgcHJvYmxlbTogVG8gaW5mZXIgdGhlIG1lYW4gJFxtdSQgb2YgYSAkXG1hdGhzZntOfVxsZWZ0KFxtdT0zLFxzaWdtYT0wLjVccmlnaHQpJCBhc3N1bWluZyB0aGF0IHdlIGtub3duIGl0cyBzdGFuZGFyZCBkZXZpYXRpb24gJFxzaWdtYT0wLjUkLiBXZSBmaXJzdCBzaW11bGF0ZSBzb21lIGRhdGE6DQoNCmBgYHtyfQ0KTiA8LSAzMDAwDQp4Lm11IDwtIDMNCnguc2lnbWEgPC0gMC41DQp4LnNhbXBsZXMgPC0gcm5vcm0oTiwgeC5tdSAsIHguc2lnbWEpDQpoaXN0KHguc2FtcGxlcyxicmVha3M9MTAwLHhsYWI9IngiLG1haW49IiIsZnJlcT1GQUxTRSkNCmBgYA0KDQpBIG1vZGVsIGZvciB0aGlzIHByb2JsZW0gaXM6DQokJA0KcFxsZWZ0KFxtYXRoY2Fse0R9LFxtdVxyaWdodCk9XHByb2Rfe2k9MX1ee059cFxsZWZ0KFxoYXR7eH1fe2l9XG1pZFxtdVxyaWdodClcdGltZXMgcFxsZWZ0KFxtdVxyaWdodCkNCiQkDQp3aGVyZSAkXGhhdHt4fV97aX1cbWlkXG11XHNpbVxtYXRoc2Z7Tn1cbGVmdChcbXUsNFxyaWdodCkkLCAkXG11XHNpbVxtYXRoc2Z7Tn1cbGVmdCgwLFxzaWdtYV97MH1ccmlnaHQpJCwgd2l0aCAkXHNpbSQgbWVhbmluZyAqZGlzdHJpYnV0ZWQgYXMqLCBhbmQgJFxzaWdtYV8wJCBpcyBhIGh5cGVycGFyYW1ldGVyIHRoYXQgcmVwcmVzZW50cyBvdXIgdW5jZXJ0YWludHkgYWJvdXQgb3VyIHByaW9yIGtub3dsZWRnZSBhYm91dCB0aGUgdHJ1ZSB2YWx1ZSBvZiB0aGUgbWVhbiwgd2hpY2ggd2UgYXNzdW1lIHRvIGJlIDAuIA0KDQpGb3IgYSBiZXR0ZXIgdW5kZXJzdGFuZGluZyBvZiB0aGUgIGRlcGVuZGVuY3kgc3RydWN0dXJlIGJldHdlZW4gdmFyaWFibGVzIGl0IGlzIGN1c3RvbWFyeSB0byByZXByZXNlbnQgdGhlIG1vZGVsIGJ5IHVzaW5nIHRoZSBCYXllc2lhbiBuZXR3b3JrIGZvcm1hbGlzbSwgd2hpY2ggY29uc2lzdHMgb2YgZHJhd2luZyBhIERBRyAoZGlyZWN0ZWQgYWN5Y2xpYyBncmFwaCkgd2hvc2UgdG9wb2xvZ3kgcmVwcmVzZW50cyB0aGUgZmFjdG9yaXphdGlvbiBvZiB0aGUgam9pbnQgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uICRwXGxlZnQoXG1hdGhjYWx7RH0sXFRoZXRhXHJpZ2h0KSQuIFNvLCB3ZSBhc3NpZ24gdG8gZWFjaCBub2RlIG9mIHRoZSBEQUcgYSBmYWN0b3IgZGlzdHJpYnV0aW9uIG9mICRwXGxlZnQoXG1hdGhjYWx7RH0sXFRoZXRhXHJpZ2h0KSQuIElmIHRoZSBmYWN0b3IgZGlzdHJpYnV0aW9uIGlzIGEgY29uZGl0aW9uYWwgZGlzdHJpYnV0aW9uLCB0aGVuIHRoZSBub2RlIHBhcmVudHMgYXJlIHRoZSBwYXJhbWV0ZXJzIG9mIHRoZSBkaXN0cmlidXRpb24gYW5kIGlmIHRoZSBmYWN0b3IgZGlzdHJpYnV0aW9uIGlzIGFuIHVuY29uZGl0aW9uYWwgKG1hcmdpbmFsKSBkaXN0cmlidXRpb24sIHRoZSBub2RlIGhhcyBubyBwYXJlbnRzLiAgICANCg0KDQpOb3csIHRvIGRlY2xhcmUgYW5kIGRyYXcgdGhlIERBRyBjb3JyZXNwb25kaW5nIHRvIG91ciB0b3kgbW9kZWwgd2UgdXNlIHRoZSBbZG90IGxhbmd1YWdlXShodHRwOi8vd3d3LmdyYXBodml6Lm9yZy9Eb2N1bWVudGF0aW9uL2RvdGd1aWRlLnBkZikgYW5kIGNhbGwgdGhlIGBnclZpemAgZnVuY3Rpb24gb2YgdGhlIGBEaWFncmFtbWVSYCBwYWNrYWdlLiAgIA0KDQpgYGB7cn0NCmxpYnJhcnkoRGlhZ3JhbW1lUikNCmBgYA0KDQpgYGB7cn0NCmdyVml6KCINCiAgZGlncmFwaCBCR01leGFtcGxlMSB7DQoNCiAgICBtYXJnaW49MDsNCiAgICByYXRpbz0wLjY7IA0KICAgIGNvbXBvdW5kPXRydWU7IA0KICAgIG5vZGVbc3R5bGU9ZmlsbGVkLHNoYXBlPWNpcmNsZSxjb2xvcj1ibGFjaywgZmlsbGNvbG9yPWNhZGV0Ymx1ZTMsZml4ZWRzaXplPWZhbHNlXTsNCiAgICByYW5rZGlyID1UQjsNCiAgICANCiAgICBzdWJncmFwaCBjbHVzdGVyMCB7DQogICAgICANCiAgICAgIGxhYmVsPSdOJzsNCg0KICAgICAgIyBPYnNlcnZhdGlvbnMNCiAgICAgICMgaHR0cHM6Ly9naXRodWIuY29tL3JpY2gtaWFubm9uZS9EaWFncmFtbWVSL2lzc3Vlcy83MQ0KICAgICAgeF9yZWNbbGFiZWw9J3gmIzc3MDtAX3tpfScsc2hhcGU9ZG91YmxlY2lyY2xlXTsgDQogICAgfQ0KDQogICAgIyBQYXJhbWV0ZXJzDQogICAgbXVbbGFiZWw9JyZtdTsnXTsNCiAgICBzaWdtYVtsYWJlbD0nJnNpZ21hOycsc2hhcGU9c3F1YXJlXTsNCg0KICAgIyBMaW5rcyB0byBvYnNlcnZlZCBub2Rlcw0KICAgIG11IC0+IHhfcmVjOw0KICAgIHNpZ21hIC0+IHhfcmVjOw0KICB9DQogIiwgd2lkdGggPSA0MDAsIGhlaWdodCA9IDQwMCAgKQ0KYGBgDQoNClRvIGRvIHRoZSBCYXllc2lhbiBhbmFseXNpcyB3ZSBuZWVkIGEgcHJvYmFiaWxpc3RpYyBtb2RlbGxpbmcgbGFuZ3VhZ2UgaW4gd2hpY2ggd2UgY2FuIGRlY2xhcmUgb3VyIG1vZGVsIGFuZCBhIE1DTUMgc2FtcGxlciB0byBwZXJmb3JtIHRoZSBpbmZlcmVuY2UuIEluIHRoaXMgdHV0b3JpYWwgd2UgdXNlIHRoZSBbU3RhbiBsYW5ndWFnZV0oaHR0cDovL21jLXN0YW4ub3JnL3VzZXJzL2RvY3VtZW50YXRpb24vaW5kZXguaHRtbCkgYW5kIGl0cyBkZWZhdWx0IHNhbXBsZXIgTlVUUyAoTm8tVS1UdXJuIHNhbXBsZXIpLiBUbyBydW4gU3RhbiBmcm9tIFIgd2UgbG9hZCB0aGUgaW50ZXJmYWNlIFtyc3Rhbl0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3JzdGFuL3JzdGFuLnBkZik6DQoNCg0KYGBge3J9DQpsaWJyYXJ5KHJzdGFuKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KcnN0YW5fb3B0aW9ucyhhdXRvX3dyaXRlID0gVFJVRSkNCm9wdGlvbnMobWMuY29yZXMgPSBwYXJhbGxlbDo6ZGV0ZWN0Q29yZXMoKSkNCmBgYA0KDQpXZSBkZWZpbmUgbm93IHRoZSBTdGFuIG1vZGVsIGZvciBvdXIgdG95IHByb2JsZW06DQoNCmBgYHtyfQ0Kc3RhbkJHTTEgPC0nDQogIGRhdGEgeyAgICAgICAgICAgICAgICAgICAgIA0KICAgIGludDxsb3dlcj0wPiBOOyAgICAgICAgICAgIA0KICAgIHZlY3RvcltOXSBvYnN4OyAgICAgICAgICAgDQogICAgcmVhbDxsb3dlcj0wPiBzaWdtYTsNCiAgICByZWFsPGxvd2VyPTA+IHNpZ21hMDsNCiAgfQ0KICBwYXJhbWV0ZXJzIHsgICAgICAgICAgICAgICAgDQogICAgcmVhbCBtdTsNCiAgfQ0KICBtb2RlbCB7ICAgICAgICAgICAgICAgICAgICANCiAgICAvL3ByaW9yDQogICAgbXUgfiBub3JtYWwoMCwgc2lnbWEwKTsgICAgICAgICAgICAgDQogDQogICAgLy9saWtlbGlob29kDQogICAgZm9yIChuIGluIDE6Tikgew0KICAgICAgb2JzeFtuXSB+IG5vcm1hbChtdSwgc2lnbWEpOw0KICAgIH0NCiAgfQ0KJw0KYGBgDQoNCk5vdywgd2UgbG9hZCBvdXIgZGF0YSBpbnRvIGEgbGlzdCwgY2FsbCB0aGUgc2FtcGxlciBhbmQgc3RvcmUgdGhlIHJlc3VsdHMgb2YgdGhlIGZpdDoNCg0KDQpgYGB7cn0NCiMgTG9hZCBkYXRhIA0KZGF0ID0gbGlzdChOID0gTiwgb2JzeD14LnNhbXBsZXMsIHNpZ21hPXguc2lnbWEsIHNpZ21hMD0xMDApDQoNCnNldC5zZWVkKDEyMzU0KQ0KDQoNCmZpdDEgPC0gc3Rhbihtb2RlbF9jb2RlID0gc3RhbkJHTTEsIGRhdGEgPSBkYXQsIGNoYWlucyA9IDMsICBpdGVyID0gNjAwMCAgLCB3YXJtdXAgPSAzMDAwLCB2ZXJib3NlID0gRkFMU0UpDQoNCmBgYA0KDQoNCg0KRmluYWxseSwgd2UgcHJpbnQgdGhlIHJlc3VsdHMgYW5kIHBsb3QgdGhlIE1hcmtvdiBjaGFpbnMgYW5kIGEgaGlzdG9ncmFtIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHBvc3RlcmlvciBzYW1wbGVzIG9mICRcbXUkOiAgDQoNCmBgYHtyfQ0KIyBzdW1tYXJ5DQpwcmludChmaXQxLCBkaWdpdHNfc3VtbWFyeT00KQ0Kc3Rhbl90cmFjZShmaXQxLHBhcnM9YygibXUiKSx1bmNvbnN0cmFpbiA9IEZBTFNFKQ0Kc3Rhbl9oaXN0KGZpdDEscGFycz1jKCJtdSIpLHVuY29uc3RyYWluID0gRkFMU0UpDQpgYGANCg0KDQoNCg0KDQojIyBIaWVyYXJjaGljYWwgTW9kZWxsaW5nDQoNCg0KQSBoaWVyYXJjaGljYWwgQmF5ZXNpYW4gbW9kZWwgKEhCTSkgZGl2aWRlcyB0aGUgdmFyaWFiaWxpdHkgb2YgYSBzdGF0aXN0aWNhbCBwcm9ibGVtIGludG8gc2V2ZXJhbCBsZXZlbHMuIA0KDQpDb25zaWRlciB0aGUgZm9sbG93aW5nIHByb2JsZW06IFRvIGluZmVyIHRoZSBtZWFuICRcbXUkIGFuZCB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uICRcc2lnbWEkIG9mIGEgR2F1c3NpYW4gcG9wdWxhdGlvbiBmcm9tICROJCBzYW1wbGVzIG9mIG9ic2VydmVkIHZhbHVlcyB3aXRoIHRoZWlyIGNvcnJlc3BvbmRpbmcgdW5jZXJ0YWludGllcy4gRmlyc3QsIGxldCB1cyB0byBzaW11bGF0ZSBzb21lIGRhdGE6DQoNCg0KYGBge3J9DQpOIDwtIDUwMA0KeC5tdSA8LSAzDQp4LnNpZ21hIDwtIDAuNQ0KeC5zYW1wbGVzIDwtIHJub3JtKE4sIHgubXUgLCB4LnNpZ21hKQ0KeC5vYnMuZXJyb3JzIDwtIHJub3JtKE4sMCwxKSANCngub2JzLmVycm9ycyA8LSBhYnMoeC5vYnMuZXJyb3JzKQ0KeC5vYnMuc2FtcGxlcyA8LSBybm9ybShOLCB4LnNhbXBsZXMsIHgub2JzLmVycm9ycykgIA0KaGlzdCh4LnNhbXBsZXMsYnJlYWtzPTEwMCx4bGFiPSJ4IixtYWluPSIiLGZyZXE9RkFMU0UseGxpbT1jKDAsNikseWxpbT1jKDAsMSkpDQpoaXN0KHgub2JzLnNhbXBsZXMsYnJlYWtzPTEwMCx4bGFiPSJ4IixtYWluPSIiLGZyZXE9RkFMU0UseGxpbT1jKDAsNikseWxpbT1jKDAsMSkpDQpgYGANCg0KDQpBIHN1aXRhYmxlIG1vZGVsIGZvciB0aGlzIHByb2JsZW0gaXM6DQoNCiQkDQpwXGxlZnQoXG1hdGhjYWx7RH0sXG11XHJpZ2h0KT1wXGxlZnQoXG11XHJpZ2h0KVxjZG90IHBcbGVmdChcc2lnbWFccmlnaHQpXHByb2Rfe2k9MX1ee059cFxsZWZ0KFxoYXR7eH1fe2l9XG1pZCB4X3tpfVxyaWdodClcY2RvdCBwXGxlZnQoeF97aX1cbWlkXG11LFxzaWdtYVxyaWdodCkNCiQkDQoNCndoZXJlICRcaGF0e3h9X3tpfVxtaWQgeF97aX1cc2ltXG1hdGhzZntOfVxsZWZ0KHhfe2l9LFxzaWdtYV97eF97aX19XHJpZ2h0KSQsICR4X3tpfVxtaWRcbXUsXHNpZ21hXHNpbVxtYXRoc2Z7Tn1cbGVmdChcbXUsXHNpZ21hXHJpZ2h0KSQsICRcbXVcc2ltXG1hdGhzZntOfVxsZWZ0KFxtdV97MH0sXHNpZ21hX3swfVxyaWdodCkkIGFuZCAkXHNpZ21hXHNpbVxtYXRoc2Z7VX1cbGVmdCgwLGtccmlnaHQpJC4gVGhhdCBpcywgd2UgZGlzdGluZ3Vpc2ggYmV0d2VlbiB0aGUgaW50cmluc2ljIHZhcmlhYmlsaXR5IG9mIHRoZSBzdGF0aXN0aWNhbCBwcm9ibGVtICh0aGUgdmFyaWFiaWxpdHkgYXQgYSBwb3B1bGF0aW9uIGxldmVsKSBhbmQgdGhlIHZhcmlhYmlsaXR5IG9mIGVhY2ggb2JzZXJ2YXRpb24uDQoNCg0KTm93LCB3ZSBkZWNsYXJlIGFuZCBkcmF3IHRoZSBEQUcgY29ycmVzcG9uZGluZyB0byBvdXIgSEJNOg0KDQpgYGB7cn0NCmdyVml6KCINCiAgZGlncmFwaCBCR01leGFtcGxlMiB7DQoNCiAgICBtYXJnaW49MDsNCiAgICByYXRpbz0wLjY7IA0KICAgIGNvbXBvdW5kPXRydWU7IA0KICAgIG5vZGVbc3R5bGU9ZmlsbGVkLHNoYXBlPWNpcmNsZSxjb2xvcj1ibGFjaywgZmlsbGNvbG9yPWdyYXksZml4ZWRzaXplPWZhbHNlXTsNCiAgICByYW5rZGlyID1UQjsNCiAgICANCiAgICBzdWJncmFwaCBjbHVzdGVyMCB7DQogICAgICANCiAgICAgIGxhYmVsPSdOJzsNCiAgICAgIA0KICAgICAgIyBQYXJhbWV0ZXJzDQogICAgICB4W2xhYmVsPSd4QF97aX0nXTsNCg0KDQogICAgICAjIE9ic2VydmF0aW9ucw0KICAgICAgIyBodHRwczovL2dpdGh1Yi5jb20vcmljaC1pYW5ub25lL0RpYWdyYW1tZVIvaXNzdWVzLzcxDQogICAgICB4X3JlY1tsYWJlbD0neCYjNzcwO0Bfe2l9JyxzaGFwZT1kb3VibGVjaXJjbGUsZmlsbGNvbG9yPWRlZXBza3libHVlMV07IA0KICAgIH0NCg0KICAgICMgSHlwZXJwYXJhbWV0ZXJzDQogICAgbXVbbGFiZWw9JyZtdTsnLGZpbGxjb2xvcj1kYXJrc2VhZ3JlZW4zXTsNCiAgICBzaWdtYVtsYWJlbD0nJnNpZ21hOycsZmlsbGNvbG9yPWRhcmtzZWFncmVlbjNdOw0KDQogICAjIExpbmtzIA0KICAgIG11IC0+IHg7DQogICAgc2lnbWEgLT4geDsNCiAgICB4IC0+IHhfcmVjOw0KICB9DQogIiwgd2lkdGggPSA2MDAsIGhlaWdodCA9IDYwMCAgKQ0KYGBgDQoNCldlIGRlZmluZSBub3cgdGhlIFN0YW4gbW9kZWwgZm9yIG91ciBzZWNvbmQgcHJvYmxlbToNCg0KYGBge3J9DQpzdGFuQkdNMiA8LScNCiAgZGF0YSB7ICAgICAgICAgICAgICAgICAgICAgDQogICAgaW50PGxvd2VyPTA+IE47ICAgICAgICAgICAgDQogICAgdmVjdG9yW05dIG9ic3g7ICAgICAgICAgICANCiAgICB2ZWN0b3I8bG93ZXI9MD5bTl0gc2lnbWFvYnN4OyAgICAgICANCiAgfQ0KICBwYXJhbWV0ZXJzIHsgICAgICAgICAgICAgICAgDQogICAgcmVhbCBtdTsNCiAgICByZWFsPGxvd2VyPTA+IHNpZ21hOw0KICAgIHZlY3RvcltOXSB4OyAgIA0KICB9DQogIG1vZGVsIHsgICAgICAgICAgICAgICAgICAgIA0KICAgICMgaHlwZXJwcmlvcnMNCiAgICBtdSB+IG5vcm1hbCgwLCAxMCk7IA0KICAgIHNpZ21hIH4gdW5pZm9ybSgwLCAxMCk7ICAgIA0KDQogICAgIyBwcmlvcnMNCiAgICBmb3IgKG4gaW4gMTpOKSB7DQogICAgICB4W25dIH4gbm9ybWFsKG11LCBzaWdtYSk7DQogICAgDQogICAgIyBMaWtlbGlob29kICANCiAgICAgIG9ic3hbbl0gfiBub3JtYWwoeFtuXSwgc2lnbWFvYnN4W25dKTsNCiAgICB9DQogIH0NCicNCmBgYA0KDQpGaW5hbGx5LCB3ZSAgY2FsbCB0aGUgc2FtcGxlciBhbmQgIHByaW50IHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGUgcG9zdGVyaW9yIHNhbXBsZXMgZm9yIHRoZSB0aGUgcGFyYW1ldGVycyAkXG11JCBhbmQgJFxzaWdtYSQuDQoNCmBgYHtyfQ0KIyBDcmVhdGUgdGhlIGRhdGEgbGlzdCBvYmplY3QNCmRhdCA9IGxpc3QoTiA9IE4sIG9ic3g9eC5vYnMuc2FtcGxlcywgc2lnbWFvYnN4PXgub2JzLmVycm9ycykNCg0KDQpmaXQxIDwtIHN0YW4obW9kZWxfY29kZSA9IHN0YW5CR00yLCBjaGFpbnMgPSAxLCBkYXRhID0gZGF0LCBpdGVyID0gMSwgdmVyYm9zZSA9IEZBTFNFKQ0KDQpzZXQuc2VlZCgxMjM1NCkNCg0KZml0MiA9IHN0YW4oZml0PWZpdDEgLCBkYXRhID0gZGF0LCAgaXRlciA9IDUwMDAgICwgd2FybXVwID0gMzAwMCwgY2hhaW5zID0gMykNCg0KYGBgDQoNCmBgYHtyfQ0KIyBzdW1tYXJ5DQpwcmludChmaXQyLCBwYXJzPWMoIm11Iiwic2lnbWEiKSwgZGlnaXRzX3N1bW1hcnk9NCkNCmBgYA0KDQoNCkluIHRoZSBmb3JtZXIgZXhhbXBsZSB3ZSBoYXZlIG1vZGVsbGVkIHRoZSBtZWFuICR4X2kkIG9mIGVhY2ggaW5kaXZpZHVhbCBvYnNlcnZhdGlvbiAgJFxoYXQgeF9pJCAgYW5kIHRoZSBtZWFuICRcbXUkIGF0IGEgcG9wdWxhdGlvbiBsZXZlbC4gQXMgYSBjb25zZXF1ZW5jZSwgd2Ugb2J0YWluIHNocnVua2VuIChyZWd1bGFyaXplZCkgcG9zdGVyaW9yIGVzdGltYXRlcyBmb3IgZWFjaCAkeF9pJC4gTGV0IHVzIGNvbXBhcmUgdGhlIHJlc3VsdHMgd2l0aCBhIG5vbi1oaWVyYXJjaGljYWwgcG9vbGVkIGVzdGltYXRpb246DQoNCmBgYHtyfQ0Kc3RhbkJHTTJwb29sZWQgPC0nDQogIGRhdGEgeyAgICAgICAgICAgICAgICAgICAgIA0KICAgIGludDxsb3dlcj0wPiBOOyAgICAgICAgICAgIA0KICAgIHZlY3RvcltOXSBvYnN4OyAgICAgICAgICAgDQogICAgdmVjdG9yPGxvd2VyPTA+W05dIHNpZ21hb2JzeDsgICAgICAgDQogIH0NCiAgcGFyYW1ldGVycyB7ICAgICAgICAgICAgICAgIA0KICAgIHJlYWwgbXU7DQogIH0NCiAgbW9kZWwgeyAgICAgICAgICAgICAgICAgICAgDQogICAgIyBwcmlvcnMNCiAgICBtdSB+IG5vcm1hbCgwLCAxMCk7IA0KDQogICAgZm9yIChuIGluIDE6Tikgew0KDQogICAgIyBMaWtlbGlob29kICANCiAgICAgIG9ic3hbbl0gfiBub3JtYWwobXUsIHNpZ21hb2JzeFtuXSk7DQogICAgfQ0KICB9DQonDQpgYGANCg0KYGBge3J9DQojIENyZWF0ZSB0aGUgZGF0YSBsaXN0IG9iamVjdA0KZGF0ID0gbGlzdChOID0gTiwgb2JzeD14Lm9icy5zYW1wbGVzLCBzaWdtYW9ic3g9eC5vYnMuZXJyb3JzKQ0KDQoNCmZpdDIxIDwtIHN0YW4obW9kZWxfY29kZSA9IHN0YW5CR00ycG9vbGVkLCBjaGFpbnMgPSAxLCBkYXRhID0gZGF0LCBpdGVyID0gMSwgdmVyYm9zZSA9IEZBTFNFKQ0KDQpzZXQuc2VlZCgxMjM1NCkNCg0KZml0MjIgPSBzdGFuKGZpdD1maXQyMSAsIGRhdGEgPSBkYXQsICBpdGVyID0gNTAwMCAgLCB3YXJtdXAgPSAzMDAwLCBjaGFpbnMgPSAzKQ0KDQoNCmBgYA0KDQpgYGB7cn0NCiMgc3VtbWFyeQ0KcHJpbnQoZml0MjIsIGRpZ2l0c19zdW1tYXJ5PTQpDQpgYGANCg0KDQpXZSBzZWUgdGhhdCB0aGUgaGllcmFyY2hpY2FsIG1vZGVsIGltcHJvdmVzIHRoZSBlc3RpbWF0aW9uIG9mIHRoZSB0cnVlIG1lYW4gJFxtdT0kIGByIHgubXVgLiBJbiBmYWN0LCAgdGhlIG1lYW4gdmFsdWUgb2YgJFxtdSQgaW5mZXJyZWQgYnkgdGhlIHRoZSBIQk0gaXMgYHIgc3VtbWFyeShmaXQyKSRzdW1tYXJ5WywibWVhbiJdWyJtdSJdYCB3aGlsZSB0aGUgbWVhbiB2YWx1ZSBpbmZlcnJlZCBieSB0aGUgcG9vbGVkIGVzdGltYXRvciBpcyAgIGByIHN1bW1hcnkoZml0MjIpJHN1bW1hcnlbLCJtZWFuIl1bIm11Il1gLg0KDQoNCiMjIEhpZXJhcmNoaWNhbCBNb2RlbGxpbmcgZm9yIFJlZ3Jlc3Npb24NCg0KSW4gdGhpcyBzZWN0aW9uIHdlIGNvbnN0cnVjdCBhIEhCTSB0aGF0IGluZmVycyB0aGUgcGFyYW1ldGVycyBvZiBhbiBpbnRyaW5zaWMgbGluZWFyIGRlcGVuZGVuY3kgcmVsYXRpb25zaGlwIG9mIHRoZSB2YXJpYWJsZSB5IG9uIHRoZSB2YXJpYWJsZSB4IHRha2luZyBpbnRvIGFjY291bnQgdGhlIG1lYXN1cmVtZW50IGVycm9ycyBvZiBib3RoIHZhcmlhYmxlcy4NCg0KDQoNCmBgYHtyfQ0KIyANCk4gPSAyMDANCngubXUgPSAtMC4yNzc5MA0KeC5zaWdtYSA9IDAuMDc2DQoNCnguc2FtcGxlcyA9IHJub3JtKE4sIHgubXUgLCB4LnNpZ21hKQ0KeC5vYnMuZXJyb3JzIDwtIHJub3JtKE4sMCwwLjEpIA0KeC5vYnMuZXJyb3JzIDwtIGFicyh4Lm9icy5lcnJvcnMpDQp4Lm9icy5zYW1wbGVzIDwtIHJub3JtKE4sIHguc2FtcGxlcywgeC5vYnMuZXJyb3JzKSAgDQoNCiMgDQojIA0KeS5zbG9wZSA9IC0yLjczDQp5LmludGVyY2VwdCA9IC0xLjI0DQp5LnNpZ21hID0gMC4wNQ0KeS5zYW1wbGVzID0gcm5vcm0oTiwgeS5zbG9wZSp4LnNhbXBsZXMgKyB5LmludGVyY2VwdCAsIHkuc2lnbWEpDQp5Lm9icy5lcnJvcnMgPC0gcm5vcm0oTiwwLDAuMSkNCnkub2JzLmVycm9ycyA8LSBhYnMoeS5vYnMuZXJyb3JzKQ0KeS5vYnMuc2FtcGxlcyA8LSBybm9ybShOLCB5LnNhbXBsZXMsIHkub2JzLmVycm9ycykgDQoNCg0KcGxvdCh4LnNhbXBsZXMsIHkuc2FtcGxlcywgYXNwID0gMSApDQpwbG90KHgub2JzLnNhbXBsZXMsIHkub2JzLnNhbXBsZXMsIGFzcCA9IDEgKQ0KDQpoaXN0KHkuc2FtcGxlcyxicmVha3M9MTAwKQ0KaGlzdCgxMF4oeC5zYW1wbGVzKSxicmVha3M9MTAwKQ0KY29yKHguc2FtcGxlcyx5LnNhbXBsZXMpDQpjb3IoeC5vYnMuc2FtcGxlcyx5Lm9icy5zYW1wbGVzKQ0KYGBgDQoNCg0KDQoNCmBgYHtyfQ0KIyBDcmVhdGUgdGhlIHN0YW4gbW9kZWwgb2JqZWN0DQpzdGFubW9kZWxjb2RlIDwtJw0KZGF0YSB7ICAgICAgICAgICAgICAgICAgICAgIA0KICBpbnQ8bG93ZXI9MD4gTjsgICAgICAgICAgIA0KICB2ZWN0b3JbTl0gb2JzeDsgICAgICAgICAgICAgIA0KICB2ZWN0b3JbTl0gb2JzeTsgICAgICAgICAgICAgDQogIHZlY3Rvcjxsb3dlcj0wPltOXSBzaWdtYW9ic3g7ICAgICAgIA0KICB2ZWN0b3I8bG93ZXI9MD5bTl0gc2lnbWFvYnN5OyAgICAgICAgDQp9DQpwYXJhbWV0ZXJzIHsgICAgICAgICAgICAgICAgIA0KICByZWFsIG11Ow0KICByZWFsIGFscGhhOyAgICAgICAgICAgICAgIA0KICByZWFsIGJldGExOw0KICByZWFsPGxvd2VyPTA+IHNpZ21hOw0KICByZWFsPGxvd2VyPTA+IHNpZ21heDsNCiAgdmVjdG9yW05dIHg7ICAgICAgICAgICAgICAgDQogIHZlY3RvcltOXSB5Ow0KfQ0KbW9kZWwgeyAgICAgICAgICAgICAgICAgICAgDQogIC8vcHJpb3JzDQogIGFscGhhIH4gbm9ybWFsKDAsIDEwKTsgICAgICAgICAgICAgDQogIGJldGExIH4gbm9ybWFsKDAsIDEwKTsNCiAgc2lnbWEgfiB1bmlmb3JtKDAsIDEwKTsgICANCiAgc2lnbWF4IH4gdW5pZm9ybSgwLCAxMCk7DQogDQovL2xpa2VsaWhvb2QNCiAgZm9yIChuIGluIDE6Tikgew0KICAgIHhbbl0gfiBub3JtYWwobXUsIHNpZ21heCk7DQogICAgeVtuXSB+IG5vcm1hbChhbHBoYSArIGJldGExICogeFtuXSwgc2lnbWEpOw0KICAgIA0KICAgIC8vIExpa2VsaWhvb2QgY29tcG9uZW50cw0KDQogICAgb2JzeFtuXSB+IG5vcm1hbCh4W25dLCBzaWdtYW9ic3hbbl0pOw0KICAgIG9ic3lbbl0gfiBub3JtYWwoeVtuXSwgc2lnbWFvYnN5W25dKTsNCg0KICB9DQp9DQonDQpgYGANCg0KDQpgYGB7cn0NCiMgQ3JlYXRlIHRoZSBkYXRhIGxpc3Qgb2JqZWN0DQpkYXQgPSBsaXN0KE4gPSBOLCBvYnN5PXkub2JzLnNhbXBsZXMsIG9ic3g9eC5vYnMuc2FtcGxlcyxzaWdtYW9ic3k9eS5vYnMuZXJyb3JzLHNpZ21hb2JzeD14Lm9icy5lcnJvcnMpDQoNCg0KZml0MSA8LSBzdGFuKG1vZGVsX2NvZGUgPSBzdGFubW9kZWxjb2RlLCBjaGFpbnMgPSAxLCBkYXRhID0gZGF0LCBpdGVyID0gMSwgdmVyYm9zZSA9IEZBTFNFKQ0KDQpzZXQuc2VlZCgxMjM1NCkNCg0KZml0MiA9IHN0YW4oZml0PWZpdDEgLCBkYXRhID0gZGF0LCAgaXRlciA9IDUwMDAgICwgd2FybXVwID0gMzAwMCwgY2hhaW5zID0gMykNCg0KIyBzdW1tYXJ5DQoNCnByaW50KGZpdDIsIGRpZ2l0c19zdW1tYXJ5PTQpDQpgYGANCg0KDQoNCg0KIyBCYXllc2lhbiBtb2RlbHMgdG8gSW5mZXIgUEwoWikgcmVsYXRpb25zIHVzaW5nIEdhaWEgcGFyYWxsYXhlcw0KDQpJbiB0aGlzIHNlY3Rpb24gd2UgY29uc3RydWN0IGEgSEJNIHRvIGluZmVyIGEgUGVyaW9kLUx1bW5pbm9zaXR5LU1ldGFsbGljaXR5IHJlbGF0aW9uIGZvciBSUkwgYWIgc3RhcnMgdXNpbmcgR2FpYSBwYXJhbGxheGVzIGFuZCBwaG90b21ldHJ5IGluIHRoZSBLLUJhbmQuIA0KDQpXZSBmaXJzdCBpbXBvcnQgdGhlIGxvY2FsIGZpbGUgYFJSTHlyYWUyMDBEYW1iaXMuZGF0YCBpbnRvIGEgZGF0YSBmcmFtZSBhbmQgY29tcHV0ZSBzb21lIGRlcml2ZWQgcGFyYW1ldGVyczoNCg0KDQpgYGB7cn0NCg0KZnVsbCA8LSByZWFkLnRhYmxlKCJSUkx5cmFlMjAwRGFtYmlzLmRhdCIsaGVhZGVyPVRSVUUsbmEuc3RyaW5ncyA9ICJOQSIsDQogICAgICAgICAgICAgICAgICAgY29sQ2xhc3NlcyA9YyhyZXAoImNoYXJhY3RlciIsMykscmVwKCJudW1lcmljIiw2KSwiY2hhcmFjdGVyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcCgibnVtZXJpYyIsMikscmVwKCJjaGFyYWN0ZXIiLDEpLHJlcCgibnVtZXJpYyIsMTEpKSApDQoNCg0KbiA8LSBucm93KGZ1bGwpDQpmdWxsJEswICAgIDwtIHdpdGgoZnVsbCwgWC5LbWFnLiAtIDAuMTE0KkFWICkgDQpmdWxsJGVtICAgIDwtIHdpdGgoZnVsbCwgZV8uS21hZy4pICMgRG9lcyBub3QgaW5jbHVkZSB1bmNlcnRhaW50eSBpbiBkZXJlZGRlbmluZw0KZnVsbCRlbG9nUCA8LSB3aXRoKGZ1bGwsIExvZ1AvKExvZ1AqMTAwKSApICAgDQpmdWxsJGVtZXQgIDwtIHdpdGgoZnVsbCwgMC4yKk1ldF9IYXJyaXMvKE1ldF9IYXJyaXMpICkgICAgIA0KI2F0dGFjaChmdWxsKQ0Kc3RyKGZ1bGwpDQpgYGANCg0KDQoNCkNvbHVtcyBvZiBkYXRhIGZyYW1lIGBmdWxsYCBpbmNsdWRlLCBmb3IgdGhlIGBuYCBzdGFycyBpbiB0aGUgc2FtcGxlOg0KDQoqIFRoZSAobWVhc3VyZWQpIEstYmFuZCBhcHBhcmVudCBtYWduaXR1ZGVzIChgSzBgKSwgZGVjYWRpYyBsb2dhcml0aG0gb2YgcGVyaW9kcyAgKGBMb2dQYCksIHBhcmFsbGF4ZXMgKGBwYXJhbGxheGApLCAgbWV0YWxsaWNpdGllcyAoYE1ldF9IYXJyaXNgKSBhbmQgZXh0aW5jdGlvbnMgKGBBVmApLg0KKiBUaGUgdW5jZXJ0YWludGllcyBvZiB0aGUgZm9ybWVyIHF1YW50aXRpZXM6IGBlbWAsIGBlbG9nUGAsIGBwYXJhbGxheF9lcnJvcmAgYW5kIGBlbWV0YC4NCg0KDQogJFxsZWZ0KFxoYXR7bX1fe2l9LFxsb2dcaGF0e1B9X3tpfSxcaGF0e1x2YXJwaX1fe2l9LFxoYXR7Wn1fe2l9LFxoYXR7QX1fe21fe2l9fVxyaWdodCkkDQoNCk5vdywgd2UgYXJlIGdvaW5nIHRvIGNvbnN0cnVjdCB0aGUgSEJNLiBMZXQgdXMgdG8gcHJlc2VudCBmaXJzdCB0aGUgcmVzdWx0aW5nIERBRyBhc3NvY2lhdGVkIHRvIHRoZSBtb2RlbC4gSW4gdGhlIGZvbGxvd2luZyBwYXJhZ3JhcGhzIHdlIGRldGFpbCBpdHMgY29uc3RydWN0aW9uIHByb2NlZHVyZS4NCg0KPGVtYmVkIHNyYz0iZ3JhcGguc3ZnIiB0eXBlPSJpbWFnZS9zdmcreG1sIiAvPg0KDQoNCldlIHN0YXJ0IG1vZGVsbGluZyB0aGUgc3RvY2hhc3RpYyBsaW5lYXIgcmVsYXRpb25zaGlwIA0KIA0KJCQNCk1fe2l9PWIrY1xsb2cgUF97aX0ra1pfe2l9DQokJCAgDQoNCndoZXJlICRNX3tpfSQsICRcbG9nIFBfe2l9JCBhbmQgJFpfe2l9JCBhcmUsIHJlc3BlY3RpdmVseSwgdGhlIGFic29sdXRlIG1hZ25pdHVkZSwgdGhlIGRlY2FkaWMgbG9nYXJpdGhtIG9mIHRoZSBpbnRyaW5zaWMgcGVyaW9kIGFuZCB0aGUgaW50cmluc2ljIG1ldGFsbGljaXR5IG9mIHRoZSBpLXRoIHN0YXIgaW4gdGhlIHNhbXBsZS4gTm90ZSB0aGF0IHdlIGRvIG5vdCBrbm93IHRoZSB2YWx1ZXMgb2YgdGhlIGludHJpbnNpYyAodHJ1ZSkgYXN0cm9waHlzaWNhbCBwYXJhbWV0ZXJzICRcbG9nIFBfe2l9JCBhbmQgJFpfe2l9JCwgYnV0IHdlIGRvIGtub3cgdGhlaXIgbWVhc3VyZWQgdmFsdWVzICRcbG9nXGhhdHtQfV97aX0kIGFuZCAkXGhhdHtafV97aX0kIGFuZCBhc3NvY2lhdGVkIHVuY2VydGFpbnRpZXMuIFRvIGFjY291bnQgZm9yIHRoZSBzdG9jaGFzdGljIG5hdHVyZSBvZiB0aGUgZm9ybWVyIHJlbGF0aW9uLCB3ZSBhc3NpZ24gaXQgYW4gaW50cmluc2ljIHdpZHRoICR3JC4gVGhlIG1haW4gb2JqZWN0aXZlIG9mIHRoZSBtb2RlbCBpcyB0aGVuIHRvIGluZmVyIHRoZSBwYXJhbWV0ZXJzICRiJCwgJGMkLCAkayQgYW5kICR3JCwgd2hlcmUgJGM9XHRhblxsZWZ0KFxwaGlfezF9XHJpZ2h0KSQgYW5kICRrPVx0YW5cbGVmdChccGhpX3syfVxyaWdodCkkLg0KDQpOb3csIHdlIG5lZWQgdG8gcmVsYXRlIGFic29sdXRlIG1hZ25pdHVkZXMgdG8gYXBwYXJlbnQgbWFnbml0dWRlcy4gRm9yIHRoYXQgd2UgdXNlIHRoZSBkZXRlcm1pbmlzdGljIHJlbGF0aW9uDQokJA0KbV97aX09TV97aX0tNVxsb2dcdmFycGlfe2l9KzEwK0Ffe21fe2l9fQ0KJCQNCiwgd2hlcmUgJG1fe2l9JCBpcyB0aGUgdHJ1ZSByZWRkZW5lZCBhcHBhcmVudCBtYWduaXR1ZGUgYW5kICRcdmFycGlfe2l9JCBpcyB0aGUgdHJ1ZSBwYXJhbGxheCBtZWFzdXJlZCBpbiBtYXMuIE5vdGUsIGFnYWluLCB0aGF0IHdlIGRvIG5vdCBrbm93IHRoZSB2YWx1ZXMgb2YgdHJ1ZSByZWRkZW5lZCBhcHBhcmVudCBtYWduaXR1ZGVzIGFuZCBwYXJhbGxheGVzIGJ1dCB3ZSBkbyBrbm93IHRoZWlyIG1lYXN1cmVkIHZhbHVlcyAkXGhhdHttfV97aX0kLCAkXGhhdHtcdmFycGl9X3tpfSQgYW5kIHVuY2VydGFpbnRpZXMuDQoNCg0KQXQgdGhpcyBwb2ludCB3ZSBwdXQgaW50byB0aGUgREFHIGFzc29jaWF0ZWQgdG8gb3VyIEhCTSwgYSByZWN0YW5nbGUgdGhhdCByZXBsaWNhdGVzIHdpdGggdGhlICRuJCBzdGFycyBpbiB0aGUgc2FtcGxlIGFuZCBpbmNsdWRlIGluIGl0IHRoZSBub2RlcyBjb3JyZXNwb25kaW5nIHRvIGV4dGluY3Rpb25zICRBX3ttX3tpfX0kIGFuZCB0cnVlIGFzdHJvcGh5c2ljYWwgcGFyYW1ldGVycyAkbV97aX0kLCAkTV97aX0kLCAkXGxvZyBQX3tpfSQgYW5kICRaX3tpfSQgLCBhbmQgdGhlIGFyY3MgYmV0d2VlbiB0aGVzZSBub2Rlcywgd2hpY2ggYXJlIGdpdmVuIGJ5IHRoZSB0d28gcmVsYXRpb25zIGFib3ZlLiBGb3IgZXhhbXBsZSwgd2UgZHJhdyBzb2xpZCAoc3RvY2hhc3RpYykgYXJjcyBmcm9tICRNX3tpfSQgdG8gJFxsb2cgUF97aX0kIGFuZCAkWl97aX0kIGFuZCBkYXNoZWQgKGRldGVybWluaXN0aWMpIGFyY3MgZnJvbSAkbV97aX0kIHRvICRNX3tpfSQgYW5kICRcdmFycGlfe2l9JC4gT3V0c2lkZSB0aGUgcmVjdGFuZ2xlLCB3ZSBpbmNsdWRlIHRoZSBwYXJhbWV0ZXJzICRiJCwgJFxwaGlfMSQsICRccGhpXzIkIGFuZCAkdyQgb2YgdGhlIFBMWiByZWxhdGlvbiBhbmQgdHJhY2UgdGhlIGFyY3MgZnJvbSAkTV97aX0kIHRvIHRob3NlIG5vZGVzLiBXZSBhbHNvIHNldCB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBpLXRoIGFic29sdXRlIG1hZ25pdHVkZSB0byBhIEdhdXNzaWFuIG9mIG1lYW4gJGIrY1xsb2cgUF97aX0ra1pfe2l9JCBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uICR3JC4NCg0KV2UgY29udGludWUgdGhlIGNvbnN0cnVjdGlvbiBvZiB0aGUgbW9kZWwgYW5kIHRoZSBEQUcgbGlua2luZyB0aGUgbWVhc3VyZWQgYXN0cm9waHlzaWNhbCBwYXJhbWV0ZXJzIHRvIHRoZSB0cnVlIG9uZXMuIFNvLCB3ZSBpbmNsdWRlICRcaGF0e219X3tpfSQsICRcbG9nXGhhdHtQfV97aX0kLCAkXGhhdHtcdmFycGl9X3tpfSQgYW5kICRcaGF0e1p9X3tpfSQgaW5zaWRlIHRoZSAgcmVjdGFuZ2xlIG9mIHRoZSBEQUcgYW5kIHRyYWNlIHRoZSBjb3JyZXNwb25kaW5nIHNvbGlkIChzdG9jaGFzdGljKSBhcmNzIHRvIHRoZSB0cnVlIHBhcmFtZXRlcnMuIFRvIGVhY2ggbWVhc3VyZWQgYXN0cm9waHlzaWNhbCBwYXJhbWV0ZXIgd2UgYXNzaWduIGEgR2F1c3NpYW4gZGlzdHJpYnV0aW9uIHdpdGggaXRzIG1lYW4gZXF1YWwgdG8gdGhlIHZhbHVlIG9mIHRoZSB0cnVlIHBhcmFtZXRlciBhbmQgaXRzIHN0YW5kYXJkIGRldmlhdGlvbiBlcXVhbCB0byB0aGUgdW5jZXJ0YWludHkgcHJvdmlkZWQgYnkgb3VyIGRhdGEgc2V0LiBGb3IgZXhhbXBsZSwgZm9yIHRoZSBtZWFzdXJlZCBhcHBhcmVudCBtYWduaXR1ZGUgd2UgZGVjbGFyZSAkXGhhdHttfV97aX1cc2ltXG1hdGhzZntOfVxsZWZ0KG1fe2l9LFxzaWdtYV97bV97aX19XHJpZ2h0KSQuICANCg0KTmV4dCwgd2UgYXNzaWduIHByaW9yIHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbnMgdG8gdGhlIHRydWUgYXN0cm9waHlzaWNhbCBwYXJhbWV0ZXJzICRcbG9nIFBfe2l9JCwgJFpfe2l9JCBhbmQgJFx2YXJwaV97aX0kIGFuZCB0cmFjZSB0aGUgREFHIGFyY3MgZnJvbSB0aGVzZSBhc3Ryb3BoeXNpY2FsIHBhcmFtZXRlcnMgdG8gdGhlIHBhcmFtZXRlcnMgb2YgdGhlIGRpc3RyaWJ1dGlvbnMgYXNzaWduZWQgdG8gdGhlbS4gV2Ugc2V0ICRcbG9nIFBfe2l9XHNpbVxtYXRoc2Z7Tn1cbGVmdChcbXVfe1B9PTAsXHNpZ21hX3tQfT0yXHJpZ2h0KSQsICRaX3tpfVxzaW1cbWF0aHNme059XGxlZnQoXG11X3tafT0wLFxzaWdtYV97Wn09NVxyaWdodCkkIGFuZCAkXHZhcnBpX3tpfVxzaW1cbWF0aHNme2xvZ059XGxlZnQoXGJldGEsXGdhbW1hXHJpZ2h0KSQuIE5vdGUgdGhhdCB0aGUgaHlwZXJwYXJhbWV0ZXJzIG9mIHRoZSAkXGxvZyBQX3tpfSQgYW5kICRaX3tpfSQgZGlzdHJpYnV0aW9ucyBhcmUgY29uc3RhbnQgcXVhbnRpdGllcyB3aGlsZSB0aGUgaHlwZXJwYXJhbWV0ZXJzICRcYmV0YSQgYW5kICRcZ2FtbWEkIG9mIHRoZSAkXHZhcnBpX3tpfSQgZGlzdHJpYnV0aW9uIGFyZSByYW5kb20uIEZvciB0aGVzZSBsYXR0ZXIgb25lcyB3ZSBhc3NpZ24gdGhlIGh5cGVycHJpb3JzICRcYmV0YVxzaW1cbWF0aHNme059XGxlZnQoXG11X3tcYmV0YX09MCxcc2lnbWFfe1xiZXRhfT0yXHJpZ2h0KSQgYW5kICRcZ2FtbWFcc2ltXG1hdGhzZntFeHB9XGxlZnQoMVxyaWdodCkkLiAgICANCg0KVG8gZmluaXNoIHRoZSBCR00gY29uc3RydWN0aW9uLCB3ZSBhc3NpZ24gdGhlIGZvbGxvd2luZyBwcmlvciBkaXN0cmlidXRpb25zIHRvIHRoZSBwYXJhbWV0ZXJzIG9mIHRoZSBQTFogcmVsYXRpb246ICAkYlxzaW1cbWF0aHNme059XGxlZnQoXG11X3tcYmV0YX09MCxcc2lnbWFfe1xiZXRhfT0xMFxyaWdodCkkIHRvIHRoZSBpbnRlcmNlcHQsICAkXHBoaV97MX0sXHBoaV97Mn1cc2ltXG1hdGhzZntOfVxsZWZ0KFxtdV97XHBoaX09MCxcc2lnbWFfe1xwaGl9PTMuMTQvMlxyaWdodCkkIHRvIHRoZSBzbG9wZSBhbmdsZXMgYW5kICR3XHNpbVxtYXRoc2Z7RXhwfVxsZWZ0KFxsYW1iZGFfe3d9PTFccmlnaHQpJCB0byB0aGUgc3ByZWFkLiANCg0KDQpXZSBkZWZpbmUgbm93IHRoZSBTdGFuIG1vZGVsIGZvciBvdXIgcHJvYmxlbToNCg0KYGBge3J9DQpzdGFuUExaY29kZSA8LScNCmRhdGEgew0KICBpbnQ8bG93ZXI9MT4gTjsgLy8gbnVtYmVyIG9mIG9ic2VydmF0aW9ucw0KICByZWFsIHBpW05dOyAgICAgLy8gb2JzZXJ2ZWQgcGFyYWxsYXgNCiAgcmVhbCBtW05dOyAgICAgIC8vIG9ic2VydmVkIGFwcGFyZW50IG1hZ25pdHVkZSANCiAgcmVhbCBsb2dQW05dOyAgIC8vIGRlY2FkaWMgbG9nYXJpdGhtIG9mIG9ic2VydmVkIHBlcmlvZCANCiAgI3JlYWwgYWxwaGFbTl07ICAvLyBvYnNlcnZlZCByaWdodCBhc2NlbnNpb24NCiAgI3JlYWwgZGVsdGFbTl07ICAvLyBvYnNlcnZlZCBkZWNsaW5hdGlvbg0KICByZWFsIG1ldFtOXTsgICAgLy8gb2JzZXJ2ZWQgbWV0YWxsaWNpdHkgDQogIHJlYWwgQVZbTl07DQogIA0KICByZWFsIGVwaVtOXTsgICAgLy8gbWVhc3VyZW1lbnQgZXJyb3Igb2Ygb2JzZXJ2ZWQgcGFyYWxsYXgNCiAgcmVhbCBlbVtOXTsgICAgIC8vIG1lYXN1cmVtZW50IGVycm9yIG9mIG9ic2VydmVkIChyZWRkZW5lZCkgYXBwYXJlbnQgbWFnbml0dWRlIA0KICByZWFsIGVsb2dQW05dOyAgLy8gbWVhc3VyZW1lbnQgZXJyb3Igb2YgbG9nYXJpdGhtIG9mIG9ic2VydmVkIHBlcmlvZCANCiAgcmVhbCBlYWxwaGFbTl07IC8vIG1lYXN1cmVtZW50IGVycm9yIG9mIG9ic2VydmVkIHJpZ2h0IGFzY2Vuc2lvbg0KICByZWFsIGVkZWx0YVtOXTsgLy8gbWVhc3VyZW1lbnQgZXJyb3Igb2Ygb2JzZXJ2ZWQgZGVjbGluYXRpb24NCiAgcmVhbCBlbWV0W05dOyAgIC8vIHVuY2VydGFpbnR5IG9mIG9ic2VydmVkIG1ldGFsbGljaXR5IA0KfQ0KDQpwYXJhbWV0ZXJzIHsNCiAgdmVjdG9yPGxvd2VyPTA+W05dIHBpMDsgICAvLyB0cnVlIHBhcmFsbGF4DQogIHZlY3RvcltOXSBsb2dQMDsgICAgICAgICAgLy8gZGVjYWRpYyBsb2dhcml0aG0gb2YgdHJ1ZSBwZXJpb2QgDQogIHZlY3RvcltOXSBtZXQwOyAgICAgICAgICAgLy8gdHJ1ZSBtZXRhbGxpY2l0eSANCiAgdmVjdG9yW05dIE07DQogIHJlYWwgYW5nbGU7DQogIHJlYWwgYjsNCiAgcmVhbCBjOw0KICByZWFsIGJldGE7DQogIHJlYWwgZ2FtbWE7DQogIHJlYWwgd2lkdGg7DQogICNyZWFsIGVBVjsNCn0NCg0KbW9kZWwgew0KDQogICNyZWFsIHBzOw0KICByZWFsIGE7DQogIHJlYWwgZDsNCiAgdmVjdG9yW05dIGVtdG90Ow0KICAjcmVhbCBlbXRvdFtOXTsNCg0KICB3aWR0aCB+IGV4cG9uZW50aWFsKDEpOw0KICBiZXRhIH4gbm9ybWFsKDAuMCwyLjApOyANCiAgZ2FtbWEgfiBleHBvbmVudGlhbCgxKTsNCiAgI2VBViB+IG5vcm1hbCgwLDAuMyk7ICMgUkVMQVRJVkUgZXJyb3IgaW4gZXh0aW5jdGlvbg0KICANCiAgYW5nbGUgfiBub3JtYWwoMCwzLjE0MTYvMi4wKTsNCiAgYiB+IG5vcm1hbCgwLDMuMCk7DQogICMgYyB+IG5vcm1hbCgwLDAuNSk7DQogIGMgfiBub3JtYWwoMCwzLjE0MTYvMi4wKTsNCg0KICBhID0gdGFuKGFuZ2xlKTsNCiAgZCA9IHRhbihjKTsNCg0KDQogIGZvciAoaSBpbiAxOk4pIHsNCiAgcGkwW2ldIH4gbG9nbm9ybWFsKGJldGEsZ2FtbWEpOw0KICBsb2dQMFtpXSB+IG5vcm1hbCgwLjAsMik7DQogIG1ldDBbaV0gfiBub3JtYWwoMCw1KTsNCiAgTVtpXSB+IG5vcm1hbChhKmxvZ1AwW2ldICsgZCptZXQwW2ldICsgYiwgd2lkdGgpOyANCiAgI2VtdG90W2ldID0gc3FydChlbVtpXV4yICsgKDAuMTE0KkFWW2ldKmZhYnMoZUFWKSleMik7ICANCg0KICAjQVZbaV0gfiBub3JtYWwoMCwwLjIpOw0KICAjIGxpa2VsaWhvb2QNCg0KICBtW2ldIH4gbm9ybWFsKE1baV0gLSAoNS4wKmxvZzEwKHBpMFtpXSkpICsgMTAuMCArQVZbaV0gLCBlbVtpXSk7DQogIHBpW2ldIH4gbm9ybWFsKHBpMFtpXSwgZXBpW2ldKTsNCiAgbG9nUFtpXSB+IG5vcm1hbChsb2dQMFtpXSxlbG9nUFtpXSk7DQogIG1ldFtpXSB+IG5vcm1hbChtZXQwW2ldLGVtZXRbaV0pOw0KDQogIH0NCg0KDQoNCiMgIGZvciAoaSBpbiAxOk4pIHsNCiMgICAgICAgIHBzID0gDQojICAgICAgICAgIG5vcm1hbF9scGRmKG1baV18KGEqbG9nUDBbaV0rZCptZXQwW2ldK2IpKzEwLjAtKDUuMCpsb2cxMChwaTBbaV0pKSAgLGVtdG90W2ldK3dpZHRoKSsNCiMgICAgICAgICAgICAgIG5vcm1hbF9scGRmKHBpW2ldfHBpMFtpXSxlcGlbaV0pKw0KIyAgICAgICAgICAgICAgbm9ybWFsX2xwZGYobG9nUFtpXXxsb2dQMFtpXSxlbG9nUFtpXSkrDQojICAgICAgICAgICAgICBub3JtYWxfbHBkZihtZXRbaV18bWV0MFtpXSxlbWV0W2ldKTsNCiMgICAgICAgIHRhcmdldCArPSBwczsNCiMgICAgfQ0KDQp9DQonDQpgYGANCg0KDQoNCg0KV2UgbG9hZCB0aGUgdHJhaW5pbmcgc2V0IGludG8gYSBsaXN0LCBpbml0aWFsaXplIE1hcmtvdiBjaGFpbnMgdG8gcmFuZG9tIHZhbHVlcywgY2FsbCB0aGUgc2FtcGxlciwgc3RvcmUgdGhlIGZpdCBhbmQgZXh0cmFjdCBwb3N0ZXJpb3Igc2FtcGxlcy4NCg0KYGBge3J9DQojIENyZWF0ZSBkYXRhIGxpc3Qgb2JqZWN0DQoNCmxpbmVhcl9kYXRhIDwtIGxpc3QoTj1ucm93KGZ1bGwpLCBwaT1mdWxsJHBhcmFsbGF4LCBlcGk9ZnVsbCRwYXJhbGxheF9lcnJvciwNCiAgICAgICAgICAgICAgICAgICAgbT1mdWxsJEswLCBlbT1mdWxsJGVtLA0KICAgICAgICAgICAgICAgICAgICBsb2dQPWZ1bGwkTG9nUCwgZWxvZ1A9ZnVsbCRlbG9nUCwNCiAgICAgICAgICAgICAgICAgICAgYWxwaGE9ZnVsbCRyYSwgZGVsdGE9ZnVsbCRkZWMsDQogICAgICAgICAgICAgICAgICAgIGVhbHBoYT1mdWxsJHJhX2Vycm9yLCBlZGVsdGE9ZnVsbCRkZWNfZXJyb3IsDQogICAgICAgICAgICAgICAgICAgIG1ldD1mdWxsJE1ldF9IYXJyaXMsIGVtZXQ9ZnVsbCRlbWV0LA0KICAgICAgICAgICAgICAgICAgICBBVj1mdWxsJEFWIA0KICAgICAgICAgICAgICAgICAgICApDQoNCg0Kc3RyKGxpbmVhcl9kYXRhKQ0KDQoNCmluaXRmMiA8LSBmdW5jdGlvbihjaGFpbl9pZCA9IDEpIHsNCiAgc2V0LnNlZWQoY2hhaW5faWQpDQoNCiMgQ3JlYXRlIGVtcHR5IHZhcmlhYmxlcw0KICBpbml0cGkgPSByZXAoTkEsbikNCiAgaW5pdGxvZ3AgPSByZXAoTkEsbikNCiAgaW5pdG1ldCA9IHJlcChOQSxuKQ0KICBpbml0TSA9IHJlcChOQSxuKQ0KIyBJbml0aWFsaXplIHBhcmFtZXRlcnMNCiAgbT1ybm9ybSgxLDAsMS4wKSANCiAgYW5nbGUgPSBhdGFuKG0pDQogIGI9cm5vcm0oMSwtMS4wLDAuMykNCiAgYyA9IHJub3JtKDEsMCwwLjUpDQogIGQgPSBhdGFuKGMpDQoNCiAgd2lkdGg9cmV4cCgxLDEuMCkNCiAgYmV0YT1ybm9ybSgxLDAuMCwyLjApDQogIGdhbW1hPXJleHAoMSwxLjApDQogIGVBVj1yZXhwKDEsMS4wKQ0KICANCiAgZm9yIChpIGluIDE6bikgew0KICAgIGluaXRsb2dwW2ldID0gcm5vcm0oMSxmdWxsJExvZ1BbaV0sMC4wMSkNCiAgICBpbml0bWV0W2ldID0gcm5vcm0oMSxmdWxsJE1ldF9IYXJyaXMsMC41KQ0KICAgIGluaXRNW2ldID0gcm5vcm0oMSwgbSpmdWxsJExvZ1BbaV0gKyBjKmZ1bGwkTWV0X0hhcnJpc1tpXSArIGIsIHdpZHRoKQ0KICAgIGluaXRwaVtpXSA9ICAxMF4oKGluaXRNW2ldLSBmdWxsJEswW2ldKzEwLjApLzUuMCkgIyBJbml0aWFsaXplIGFsbW9zdCBhdCByYW5kb20gKG0sYixkIGNhbiB0YWtlIGFsbW9zdCBhbnkgdmFsdWUpDQogICAgDQogICAgDQogIH0NCg0KDQoNCiBsaXN0KHBpMD1pbml0cGksDQogICAgICAgICBsb2dQMD1pbml0bG9ncCwgTT1pbml0TSwNCiAgICAgICAgICBhbmdsZT1hbmdsZSwNCiAgICAgICAgICBiPWIsIGJldGE9YmV0YSwgZ2FtbWE9Z2FtbWEsIGM9Yywgd2lkdGg9d2lkdGgsZUFWPWVBVikNCiANCiAjbGlzdChhbmdsZT1hbmdsZSwgYj1iLCBiZXRhPWJldGEsIGdhbW1hPWdhbW1hLCBjPWMsIHdpZHRoPXdpZHRoKQ0KIA0KIA0KDQp9IA0KDQojIGdlbmVyYXRlIGEgbGlzdCBvZiBsaXN0cyB0byBzcGVjaWZ5IGluaXRpYWwgdmFsdWVzDQojbl9jaGFpbnMgPC0gNA0Kbl9jaGFpbnMgPC0gMQ0KaW5pdF9sbCA8LSBsYXBwbHkoMTpuX2NoYWlucywgZnVuY3Rpb24oaWQpIGluaXRmMihjaGFpbl9pZCA9IGlkKSkNCg0KbnNhbXBsZXNfY2hhaW4gPTUwMDAgI0xTQg0KI25zYW1wbGVzX2NoYWluID0xMDAwDQpuc2FtcGxlcyA8LSBuX2NoYWlucypuc2FtcGxlc19jaGFpbi8yDQoNCmZpdCA8LSBzdGFuKG1vZGVsX2NvZGUgPSBzdGFuUExaY29kZSwgZGF0YSA9IGxpbmVhcl9kYXRhLCBpdGVyID0gbnNhbXBsZXNfY2hhaW4sIA0KICAgICAgICAgICAgY2hhaW5zID0gbl9jaGFpbnMsaW5pdD1pbml0X2xsLGNvbnRyb2w9IGxpc3QoYWRhcHRfZGVsdGEgPSAwLjgpLCB2ZXJib3NlID0gVFJVRSxpbml0X3I9MikNCg0KI2ZpdCA8LSBzdGFuKG1vZGVsX2NvZGUgPSBzdGFuUExaY29kZSwgZGF0YSA9IGxpbmVhcl9kYXRhLCBpdGVyID0gbnNhbXBsZXNfY2hhaW4sIA0KIyAgICAgICAgICAgIGNoYWlucyA9IG5fY2hhaW5zLGluaXQ9InJhbmRvbSIsY29udHJvbD0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOCksIHZlcmJvc2UgPSBUUlVFLGluaXRfcj0yKQ0KDQojZHJhd3MgPC0gZXh0cmFjdChmaXQpDQoNCmBgYA0KDQoNCkZpbmFsbHksIHdlIHBsb3QgdGhlIG1hcmdpbmFsIHBvc3RlcmlvciBkaXN0cmlidXRpb25zIGZyb20gdGhlIE1DTUMgc2FtcGxlcy5UaGUgZGlhZ29uYWwgc2hvd3MgdGhlIHVuaS1kaW1lbnNpb25hbCBtYXJnaW5hbCBkaXN0cmlidXRpb25zDQpmb3IgdGhlIGludHJpbnNpYyB3aWR0aCBvZiB0aGUgcmVsYXRpb25zaGlwLCB0aGUgYW5nbGUgb2YgdGhlIG1ldGFsbGljaXR5IHRlcm0gaW4gdGhlIGxpbmVhciByZWxhdGlvbiwgdGhlIGludGVyY2VwdCBhbmQgdGhlIGFuZ2xlIG9mIHRoZQ0KbG9nKFApIHRlcm0uDQoNCg0KDQpgYGB7cn0NCnBhaXJzKGZpdCwgcGFycyA9IGMoIndpZHRoIiwgImMiLCAiYiIsImFuZ2xlIiksIGxhYmVscz1jKCJJbnRyaW5zaWMgV2lkdGgiLCAiTWV0YWxsaWNpdHkgQW5nbGUiLCAiSW50ZXJjZXB0IiwibG9nKFApIEFuZ2xlIiksIA0KICAgICAgbG9nID0gRkFMU0UsIGxhcyA9IDEpDQpgYGANCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KIA0KDQo=